//----------------------------------------------------------------------------
// cmdline.cpp
//
// command line parsing stuff for swine
//
// Copyright (C) 2011 Neil Butterworth
//----------------------------------------------------------------------------

#include <iostream>
#include "cmdline.h"
#include "error.h"

using std::string;

namespace Swine {

//----------------------------------------------------------------------------
// Check if the command line entry at i is the specified option in either
// long or short form (e.g. --option or -o).
//----------------------------------------------------------------------------

bool CmdLine :: IsOption( const string & opt, unsigned int i ) const {
	if ( Argv( i ) == "--" + opt ) {
		return true;
	}
	else if ( Argv( i ) == "-" + opt.substr( 0, 1 ) ) {
		return true;
	}
	else {
		return false;
	}
}

//----------------------------------------------------------------------------
// Find option in command line end extract it and its parameter, returning
// the parameter. If the option is not present, return the default value.
//----------------------------------------------------------------------------

string CmdLine :: ExtractOption( const string & opt,
									const string & defval ) {
	int i = 1;
	string val;
	bool have = false;
	while( i < Argc() ) {
		if ( IsOption( opt, i ) ) {
			if ( i == Argc() - 1 ) {
				throw Error( "Invalid command line at " + Argv(i) );
			}
			val = Argv( i + 1 );
			have = true;
			mArgv.erase( mArgv.begin() + i, mArgv.begin() + i + 2 );
			break;
		}
		i++;
	}

	if ( have ) {
		return val;
	}
	else {
		return defval;
	}
}

//----------------------------------------------------------------------------
// As above, but for single option, returning true if it exists.
//----------------------------------------------------------------------------

bool CmdLine :: ExtractOption( const string & opt ) {
	int i = 1;
	bool have = false;
	while( i < Argc() ) {
		if ( IsOption( opt, i ) ) {
			have = true;
			mArgv.erase( mArgv.begin() + i, mArgv.begin() + i + 2 );
			break;
		}
		i++;
	}
	return have;
}

//----------------------------------------------------------------------------
// Check the command line is empty (contains only command name). If not,
// raise exception containing invalid options.
//----------------------------------------------------------------------------

void CmdLine :: MustBeEmpty() {
	if ( Argc() > 2 ) {
		string emsg = "Invalid option(s): ";
		for ( int i = 2; i < Argc(); i++ ) {
			emsg += Argv(i) + " ";
		}
		throw Error( emsg );
	}
}

//----------------------------------------------------------------------------
// Command line dump for debugging
//----------------------------------------------------------------------------

void CmdLine :: Dump() const {
	for ( int i = 0; i < Argc(); i++ ) {
		std::cout << i << ": " << Argv(i) << "\n";
	}
	std::cout.flush();
}

//----------------------------------------------------------------------------

} // namespace
